package org.zn.plus.mybatis.sql.builder.data.adapter;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.zn.commons.easiness.Uuids;
import org.zn.commons.tree.Tree;

public class XmlAadapterMappingParser {
	
	private	SAXReader reader;
	
	public XmlAadapterMappingParser() {
		reader=new SAXReader();
	}

	public Tree<String,AdapterMappingNode> parseMapping(InputStream source) throws DocumentException{
		
		Document doc=reader.read(source);
		
		Element rootEle=doc.getRootElement();
		
		Map<String, AdapterMappingNode> contextTemp=new HashMap<>();
		
		AdapterMappingNode root=new AdapterMappingNode();
		
		root.setNodeName(rootEle.getName());
		
		String id = rootEle.attributeValue("id")!=null?rootEle.attributeValue("id"):"root";
		root.setId(id);
		root.setModel(rootEle.attributeValue("model"));
		root.setType("root");
		
		contextTemp.put(id, root);
		
		List<Element> eles=rootEle.elements();
		
		for (Element element : eles) {
			
			root.addChild(putElement(element,contextTemp));
			
		}
		
		Tree<String,AdapterMappingNode> tree=new Tree<>(root, null);
	
		return tree;
	
	}
	
	
	private AdapterMappingNode putElement(Element e,Map<String, AdapterMappingNode> contextTemp) {
		
		AdapterMappingNode node=new AdapterMappingNode();
		
		node.setNodeName(e.getName());
		
		
		String id =e.attributeValue("id")!=null?e.attributeValue("id"):Uuids.simpleId(16);
	
		node.setId(id);
		
		contextTemp.put(id, node);

		node.setModel(e.attributeValue("model"));
		node.setType(e.attributeValue("type"));
		node.setColumn(e.attributeValue("column"));
	
		String refId=e.attributeValue("ref");
		
		if(refId!=null)	node.setRef(contextTemp.get(refId));
	
		List<Element> eles=e.elements();
		
		for (Element c : eles) {
			
			AdapterMappingNode cnode=putElement(c,contextTemp);
			
			node.addChild(cnode);
			
		}
		
		return node;
		
	}
	
	
	
	
}
